#load relevant libraries
library(dplyr)
Attaching package: ‘dplyr’
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
library(ggplot2)
#Import data into a new data frame
MasterData<-read.csv("~/downloads/FRE1120 Data Summary - RAW.csv")
#Removing students that were not required to do the LS exercises
MasterData<-MasterData[MasterData$LS.Required=="y",]
#Removing the few students with linguistic background different than English, Spnaish, or Creole due to very low numbers
MasterData<-MasterData[MasterData$Linguistic.Background %in% c("English","Creole","Spanish"),]
#Creating the calculated fields of Per_aware and Per_correct
MasterData <- MasterData %>% mutate(Per_correct = Correct...aware+Correct...unaware)
MasterData <- MasterData %>% mutate(Per_aware = Correct...aware+Incorrect...aware)
#eliminating redundant columns
MasterData<- select(MasterData, "ID..","Sex","Linguistic.Background","Final.Grade","Incorrect...unaware","Per_correct","Per_aware","Time.Spent..HW.","Time.Spent..Pronunciation.Practice.","Time.Spent..LearnSmart.","Total.HW...Correct","Total.LS...Complete",)
#Changing column names
names(MasterData) <- c("ID","Sex","Language","Final_grade","IU","Per_correct","Per_aware","Time_hw","Time_pron","Time_LS","Per_correct_hw","Per_complete_LS")
#Examine scatter plots for different variable combination pairs
#Creating scatter plots for all pairs
pairs(MasterData)

#Time spent on Connect homework, Percentage of correct homework responses
ggplot(MasterData, aes(Time_hw,Per_correct_hw))+ geom_point() + stat_sum(aes(group = 1))

#Time spent on Connect homework, Time spent on LearnSmart adaptive activities
ggplot(MasterData, aes(Time_hw,Time_LS))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of correct homework responses, Final course grade
ggplot(MasterData, aes(Per_correct_hw,Final_grade))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of correct LearnSmart responses, Percentage of awareness of correct/incorrect responses
ggplot(MasterData, aes(Per_correct,Per_aware))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of completion of assigned LearnSmart activities, Final course grade
ggplot(MasterData, aes(Per_complete_LS,Final_grade))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of completion of assigned LearnSmart activities, Percentage of incorrect and unaware LearnSmart responses
ggplot(MasterData, aes(Per_complete_LS,IU))+ geom_point() + stat_sum(aes(group = 1))

#Time spent on LearnSmart adaptive activities, Final course grade
ggplot(MasterData, aes(Time_LS,Final_grade))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of incorrect and unaware LearnSmart responses, Final course grade
ggplot(MasterData, aes(IU,Final_grade))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of incorrect and unaware LearnSmart responses, Time spent on LearnSmart adaptive activities
ggplot(MasterData, aes(IU,Time_LS))+ geom_point() + stat_sum(aes(group = 1))

#Percentage of incorrect and unaware LearnSmart responses, Time spent on Connect homework
ggplot(MasterData, aes(IU,Time_hw))+ geom_point() + stat_sum(aes(group = 1))

#Create new data frame for scaled data, removing non-clustering variables
ScaledData<-as.data.frame(cbind(MasterData[,1:3],scale(select(MasterData, Final_grade:Per_complete_LS))))
#Validating scaling by looking at means and standard deviations of the scaled columns
sapply(ScaledData[,4:12], mean)
Final_grade IU Per_correct Per_aware Time_hw Time_pron Time_LS
5.843135e-17 -1.133857e-16 2.872520e-16 -4.121555e-16 -3.776554e-17 5.052708e-17 8.279565e-17
Per_correct_hw Per_complete_LS
2.015534e-16 4.870925e-18
sapply(ScaledData[,4:12], sd)
Final_grade IU Per_correct Per_aware Time_hw Time_pron Time_LS
1 1 1 1 1 1 1
Per_correct_hw Per_complete_LS
1 1
#Creating the Within Group Sum of Squares function
wssplot <- function(data, nc=15, seed=1234){
wss <- (nrow(data)-1)*sum(apply(data,2,var))
for (i in 2:nc){
set.seed(seed)
wss[i] <- sum(kmeans(data, centers=i)$withinss)}
plot(1:nc, wss, type="b", xlab="Number of Clusters",
ylab="Within groups sum of squares")}
#Create the WSS Graph
wssplot(ScaledData[,4:12],nc=15,seed=1234)

#Create and examine several different possible cluster solutions
threeclusterkmeans<-kmeans(ScaledData[,4:12], 3, nstart=10)
threeclusterkmeans
K-means clustering with 3 clusters of sizes 15, 68, 46
Cluster means:
Final_grade IU Per_correct Per_aware Time_hw Time_pron Time_LS Per_correct_hw Per_complete_LS
1 -1.66048356 -0.4683417 0.4338804 0.2462526 -1.34682486 -0.38218605 -0.7236692 -2.050320950 -2.0744039
2 0.35681501 -0.5420303 0.4596331 0.5090781 0.02322455 -0.03493209 -0.2628125 0.450550769 0.2919678
3 0.01399637 0.9539823 -0.8209404 -0.8328501 0.40485007 0.17626462 0.6244845 0.002551347 0.2448315
Clustering vector:
[1] 3 2 2 2 1 3 3 3 2 1 3 1 2 1 3 2 2 2 1 2 2 3 2 3 1 1 2 2 3 2 2 2 1 2 3 2 1 3 3 1 3 3 3 3 3 3 2 2 2 2 3 3 3 2 2 3 3 3 2 1 2
[62] 2 3 2 2 3 2 2 1 2 2 2 2 2 3 3 3 2 2 3 2 2 2 3 2 2 3 2 1 3 3 3 2 2 1 2 2 2 3 2 2 2 3 3 2 2 2 2 2 2 3 1 3 2 2 3 3 2 2 2 2 2
[123] 3 3 3 2 2 2 3
Within cluster sum of squares by cluster:
[1] 108.0055 317.0107 294.2538
(between_SS / total_SS = 37.6 %)
Available components:
[1] "cluster" "centers" "totss" "withinss" "tot.withinss" "betweenss" "size" "iter"
[9] "ifault"
fourclusterkmeans<-kmeans(ScaledData[,4:12], 4, nstart=10)
fourclusterkmeans
K-means clustering with 4 clusters of sizes 19, 15, 37, 58
Cluster means:
Final_grade IU Per_correct Per_aware Time_hw Time_pron Time_LS Per_correct_hw Per_complete_LS
1 -0.3507149 1.1769446 -0.9840832 -1.1188646 0.87451648 1.0314872 1.5405665 -0.1017225 0.1292924
2 -1.6964014 -0.6400324 0.4608217 0.2805430 -1.33097412 -0.3821861 -0.7669705 -1.8427475 -2.1677251
3 0.5572135 -0.7840533 0.9818083 0.8836826 0.07144945 0.2390765 -0.2894854 0.5519276 0.4797214
4 0.1981501 0.2801468 -0.4231319 -0.2697582 0.01215809 -0.3915741 -0.1216422 0.1578038 0.2122350
Clustering vector:
[1] 1 4 4 4 2 4 4 4 2 2 4 2 3 2 1 3 3 3 2 4 3 4 4 4 2 2 4 3 1 3 3 4 2 4 1 3 2 1 1 2 1 1 1 1 1 4 3 4 3 3 4 4 4 4 3 1 4 4 4 2 3
[62] 3 1 4 4 4 3 4 4 3 4 3 3 3 4 1 4 4 4 4 3 4 3 4 4 4 1 4 2 4 4 4 4 3 2 3 4 3 1 3 3 3 4 4 4 4 4 4 3 3 1 2 4 4 4 4 1 3 3 3 3 3
[123] 1 4 4 4 3 3 4
Within cluster sum of squares by cluster:
[1] 162.9807 111.4874 159.6486 194.7688
(between_SS / total_SS = 45.4 %)
Available components:
[1] "cluster" "centers" "totss" "withinss" "tot.withinss" "betweenss" "size" "iter"
[9] "ifault"
#Assign the clusters for each observation for k=3,4 to a new dataframe
Clusters<-data.frame(ScaledData, as.factor(threeclusterkmeans$cluster), as.factor(fourclusterkmeans$cluster))
names(Clusters) <- c("ID","Sex","Language","Final_grade","IU","Per_correct","Per_aware","Time_hw","Time_pron","Time_LS","Per_correct_hw","Per_complete_LS","ClusterToThree","ClusterToFour")
#Graph the different solutions - Three Clusters.
#Shapes indicate Language Background. To change which variable is marked by shape, change the name of the variable in "shape=Language"
ggplot(Clusters, aes(Time_hw,Per_correct_hw, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Time_hw,Time_LS, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Per_correct_hw,Final_grade, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Per_correct,Per_aware, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Per_complete_LS,Final_grade, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Per_complete_LS,IU, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(Time_LS,Final_grade, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(IU,Final_grade, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(IU,Time_LS, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

ggplot(Clusters, aes(IU,Time_hw, group = factor(ClusterToThree))) + geom_point((aes(shape=Language, color = factor(ClusterToThree))))

#Graph the different solutions - Four Clusters.
#Shapes indicate Language Background. To change which variable is marked by shape, change the name of the variable in "shape=Language
ggplot(Clusters, aes(Time_hw,Per_correct_hw, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Time_hw,Time_LS, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Per_correct_hw,Final_grade, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Per_correct,Per_aware, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Per_complete_LS,Final_grade, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Per_complete_LS,IU, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(Time_LS,Final_grade, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(IU,Final_grade, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(IU,Time_LS, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

ggplot(Clusters, aes(IU,Time_hw, group = factor(ClusterToFour))) + geom_point((aes(size=2,shape=Language, color = factor(ClusterToFour))))

for (j in langs) {
LangsCount[j,1] <- j
for (i in 1:4){
LangsCount[j,i] <- sum(UnscaledClusters$Language==j & UnscaledClusters$ClusterToFour==i)
}
}
invalid factor level, NA generatedinvalid factor level, NA generatedinvalid factor level, NA generatedinvalid factor level, NA generatedinvalid factor level, NA generatedinvalid factor level, NA generated
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQogIApgYGB7cn0KI2xvYWQgcmVsZXZhbnQgbGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKCiNJbXBvcnQgZGF0YSBpbnRvIGEgbmV3IGRhdGEgZnJhbWUKTWFzdGVyRGF0YTwtcmVhZC5jc3YoIn4vZG93bmxvYWRzL0ZSRTExMjAgRGF0YSBTdW1tYXJ5IC0gUkFXLmNzdiIpCiNSZW1vdmluZyBzdHVkZW50cyB0aGF0IHdlcmUgbm90IHJlcXVpcmVkIHRvIGRvIHRoZSBMUyBleGVyY2lzZXMKTWFzdGVyRGF0YTwtTWFzdGVyRGF0YVtNYXN0ZXJEYXRhJExTLlJlcXVpcmVkPT0ieSIsXQojUmVtb3ZpbmcgdGhlIGZldyBzdHVkZW50cyB3aXRoIGxpbmd1aXN0aWMgYmFja2dyb3VuZCBkaWZmZXJlbnQgdGhhbiBFbmdsaXNoLCBTcG5haXNoLCBvciBDcmVvbGUgZHVlIHRvIHZlcnkgbG93IG51bWJlcnMKTWFzdGVyRGF0YTwtTWFzdGVyRGF0YVtNYXN0ZXJEYXRhJExpbmd1aXN0aWMuQmFja2dyb3VuZCAlaW4lIGMoIkVuZ2xpc2giLCJDcmVvbGUiLCJTcGFuaXNoIiksXQojQ3JlYXRpbmcgdGhlIGNhbGN1bGF0ZWQgZmllbGRzIG9mIFBlcl9hd2FyZSBhbmQgUGVyX2NvcnJlY3QKTWFzdGVyRGF0YSA8LSBNYXN0ZXJEYXRhICU+JSBtdXRhdGUoUGVyX2NvcnJlY3QgPSBDb3JyZWN0Li4uYXdhcmUrQ29ycmVjdC4uLnVuYXdhcmUpCk1hc3RlckRhdGEgPC0gTWFzdGVyRGF0YSAlPiUgbXV0YXRlKFBlcl9hd2FyZSA9IENvcnJlY3QuLi5hd2FyZStJbmNvcnJlY3QuLi5hd2FyZSkKI2VsaW1pbmF0aW5nIHJlZHVuZGFudCBjb2x1bW5zCk1hc3RlckRhdGE8LSBzZWxlY3QoTWFzdGVyRGF0YSwgIklELi4iLCJTZXgiLCJMaW5ndWlzdGljLkJhY2tncm91bmQiLCJGaW5hbC5HcmFkZSIsIkluY29ycmVjdC4uLnVuYXdhcmUiLCJQZXJfY29ycmVjdCIsIlBlcl9hd2FyZSIsIlRpbWUuU3BlbnQuLkhXLiIsIlRpbWUuU3BlbnQuLlByb251bmNpYXRpb24uUHJhY3RpY2UuIiwiVGltZS5TcGVudC4uTGVhcm5TbWFydC4iLCJUb3RhbC5IVy4uLkNvcnJlY3QiLCJUb3RhbC5MUy4uLkNvbXBsZXRlIiwpCiNDaGFuZ2luZyBjb2x1bW4gbmFtZXMKbmFtZXMoTWFzdGVyRGF0YSkgPC0gYygiSUQiLCJTZXgiLCJMYW5ndWFnZSIsIkZpbmFsX2dyYWRlIiwiSVUiLCJQZXJfY29ycmVjdCIsIlBlcl9hd2FyZSIsIlRpbWVfaHciLCJUaW1lX3Byb24iLCJUaW1lX0xTIiwiUGVyX2NvcnJlY3RfaHciLCJQZXJfY29tcGxldGVfTFMiKQoKYGBgCgpgYGB7cn0KI0V4YW1pbmUgc2NhdHRlciBwbG90cyBmb3IgZGlmZmVyZW50IHZhcmlhYmxlIGNvbWJpbmF0aW9uIHBhaXJzCiNDcmVhdGluZyBzY2F0dGVyIHBsb3RzIGZvciBhbGwgcGFpcnMKcGFpcnMoTWFzdGVyRGF0YSkKI1RpbWUgc3BlbnQgb24gQ29ubmVjdCBob21ld29yaywgUGVyY2VudGFnZSBvZiBjb3JyZWN0IGhvbWV3b3JrIHJlc3BvbnNlcwpnZ3Bsb3QoTWFzdGVyRGF0YSwgYWVzKFRpbWVfaHcsUGVyX2NvcnJlY3RfaHcpKSsgZ2VvbV9wb2ludCgpICsgc3RhdF9zdW0oYWVzKGdyb3VwID0gMSkpCiNUaW1lIHNwZW50IG9uIENvbm5lY3QgaG9tZXdvcmssIFRpbWUgc3BlbnQgb24gTGVhcm5TbWFydCBhZGFwdGl2ZSBhY3Rpdml0aWVzCmdncGxvdChNYXN0ZXJEYXRhLCBhZXMoVGltZV9odyxUaW1lX0xTKSkrIGdlb21fcG9pbnQoKSArIHN0YXRfc3VtKGFlcyhncm91cCA9IDEpKQojUGVyY2VudGFnZSBvZiBjb3JyZWN0IGhvbWV3b3JrIHJlc3BvbnNlcywgRmluYWwgY291cnNlIGdyYWRlCmdncGxvdChNYXN0ZXJEYXRhLCBhZXMoUGVyX2NvcnJlY3RfaHcsRmluYWxfZ3JhZGUpKSsgZ2VvbV9wb2ludCgpICsgc3RhdF9zdW0oYWVzKGdyb3VwID0gMSkpCiNQZXJjZW50YWdlIG9mIGNvcnJlY3QgTGVhcm5TbWFydCByZXNwb25zZXMsIFBlcmNlbnRhZ2Ugb2YgYXdhcmVuZXNzIG9mIGNvcnJlY3QvaW5jb3JyZWN0IHJlc3BvbnNlcwpnZ3Bsb3QoTWFzdGVyRGF0YSwgYWVzKFBlcl9jb3JyZWN0LFBlcl9hd2FyZSkpKyBnZW9tX3BvaW50KCkgKyBzdGF0X3N1bShhZXMoZ3JvdXAgPSAxKSkKI1BlcmNlbnRhZ2Ugb2YgY29tcGxldGlvbiBvZiBhc3NpZ25lZCBMZWFyblNtYXJ0IGFjdGl2aXRpZXMsIEZpbmFsIGNvdXJzZSBncmFkZQpnZ3Bsb3QoTWFzdGVyRGF0YSwgYWVzKFBlcl9jb21wbGV0ZV9MUyxGaW5hbF9ncmFkZSkpKyBnZW9tX3BvaW50KCkgKyBzdGF0X3N1bShhZXMoZ3JvdXAgPSAxKSkKI1BlcmNlbnRhZ2Ugb2YgY29tcGxldGlvbiBvZiBhc3NpZ25lZCBMZWFyblNtYXJ0IGFjdGl2aXRpZXMsIFBlcmNlbnRhZ2Ugb2YgaW5jb3JyZWN0IGFuZCB1bmF3YXJlIExlYXJuU21hcnQgcmVzcG9uc2VzCmdncGxvdChNYXN0ZXJEYXRhLCBhZXMoUGVyX2NvbXBsZXRlX0xTLElVKSkrIGdlb21fcG9pbnQoKSArIHN0YXRfc3VtKGFlcyhncm91cCA9IDEpKQojVGltZSBzcGVudCBvbiBMZWFyblNtYXJ0IGFkYXB0aXZlIGFjdGl2aXRpZXMsIEZpbmFsIGNvdXJzZSBncmFkZQpnZ3Bsb3QoTWFzdGVyRGF0YSwgYWVzKFRpbWVfTFMsRmluYWxfZ3JhZGUpKSsgZ2VvbV9wb2ludCgpICsgc3RhdF9zdW0oYWVzKGdyb3VwID0gMSkpCiNQZXJjZW50YWdlIG9mIGluY29ycmVjdCBhbmQgdW5hd2FyZSBMZWFyblNtYXJ0IHJlc3BvbnNlcywgRmluYWwgY291cnNlIGdyYWRlCmdncGxvdChNYXN0ZXJEYXRhLCBhZXMoSVUsRmluYWxfZ3JhZGUpKSsgZ2VvbV9wb2ludCgpICsgc3RhdF9zdW0oYWVzKGdyb3VwID0gMSkpCiNQZXJjZW50YWdlIG9mIGluY29ycmVjdCBhbmQgdW5hd2FyZSBMZWFyblNtYXJ0IHJlc3BvbnNlcywgVGltZSBzcGVudCBvbiBMZWFyblNtYXJ0IGFkYXB0aXZlIGFjdGl2aXRpZXMKZ2dwbG90KE1hc3RlckRhdGEsIGFlcyhJVSxUaW1lX0xTKSkrIGdlb21fcG9pbnQoKSArIHN0YXRfc3VtKGFlcyhncm91cCA9IDEpKQojUGVyY2VudGFnZSBvZiBpbmNvcnJlY3QgYW5kIHVuYXdhcmUgTGVhcm5TbWFydCByZXNwb25zZXMsIFRpbWUgc3BlbnQgb24gQ29ubmVjdCBob21ld29yawpnZ3Bsb3QoTWFzdGVyRGF0YSwgYWVzKElVLFRpbWVfaHcpKSsgZ2VvbV9wb2ludCgpICsgc3RhdF9zdW0oYWVzKGdyb3VwID0gMSkpCmBgYAoKYGBge3J9CiNDcmVhdGUgbmV3IGRhdGEgZnJhbWUgZm9yIHNjYWxlZCBkYXRhLCByZW1vdmluZyBub24tY2x1c3RlcmluZyB2YXJpYWJsZXMKU2NhbGVkRGF0YTwtYXMuZGF0YS5mcmFtZShjYmluZChNYXN0ZXJEYXRhWywxOjNdLHNjYWxlKHNlbGVjdChNYXN0ZXJEYXRhLCBGaW5hbF9ncmFkZTpQZXJfY29tcGxldGVfTFMpKSkpCiNWYWxpZGF0aW5nIHNjYWxpbmcgYnkgbG9va2luZyBhdCBtZWFucyBhbmQgc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiB0aGUgc2NhbGVkIGNvbHVtbnMKc2FwcGx5KFNjYWxlZERhdGFbLDQ6MTJdLCBtZWFuKQpzYXBwbHkoU2NhbGVkRGF0YVssNDoxMl0sIHNkKQpgYGAKCmBgYHtyfQojQ3JlYXRpbmcgdGhlIFdpdGhpbiBHcm91cCBTdW0gb2YgU3F1YXJlcyBmdW5jdGlvbgp3c3NwbG90IDwtIGZ1bmN0aW9uKGRhdGEsIG5jPTE1LCBzZWVkPTEyMzQpewogIHdzcyA8LSAobnJvdyhkYXRhKS0xKSpzdW0oYXBwbHkoZGF0YSwyLHZhcikpCiAgZm9yIChpIGluIDI6bmMpewogICAgc2V0LnNlZWQoc2VlZCkKICAgIHdzc1tpXSA8LSBzdW0oa21lYW5zKGRhdGEsIGNlbnRlcnM9aSkkd2l0aGluc3MpfQogIHBsb3QoMTpuYywgd3NzLCB0eXBlPSJiIiwgeGxhYj0iTnVtYmVyIG9mIENsdXN0ZXJzIiwKICAgICAgIHlsYWI9IldpdGhpbiBncm91cHMgc3VtIG9mIHNxdWFyZXMiKX0KCiNDcmVhdGUgdGhlIFdTUyBHcmFwaAp3c3NwbG90KFNjYWxlZERhdGFbLDQ6MTJdLG5jPTE1LHNlZWQ9MTIzNCkKYGBgCmBgYHtyfQojQ3JlYXRlIGFuZCBleGFtaW5lIHNldmVyYWwgZGlmZmVyZW50IHBvc3NpYmxlIGNsdXN0ZXIgc29sdXRpb25zCnRocmVlY2x1c3RlcmttZWFuczwta21lYW5zKFNjYWxlZERhdGFbLDQ6MTJdLCAzLCBuc3RhcnQ9MTApCnRocmVlY2x1c3RlcmttZWFucwpmb3VyY2x1c3RlcmttZWFuczwta21lYW5zKFNjYWxlZERhdGFbLDQ6MTJdLCA0LCBuc3RhcnQ9MTApCmZvdXJjbHVzdGVya21lYW5zCmBgYApgYGB7cn0KI0Fzc2lnbiB0aGUgY2x1c3RlcnMgZm9yIGVhY2ggb2JzZXJ2YXRpb24gZm9yIGs9Myw0IHRvIGEgbmV3IGRhdGFmcmFtZQpDbHVzdGVyczwtZGF0YS5mcmFtZShTY2FsZWREYXRhLCBhcy5mYWN0b3IodGhyZWVjbHVzdGVya21lYW5zJGNsdXN0ZXIpLCBhcy5mYWN0b3IoZm91cmNsdXN0ZXJrbWVhbnMkY2x1c3RlcikpCm5hbWVzKENsdXN0ZXJzKSA8LSBjKCJJRCIsIlNleCIsIkxhbmd1YWdlIiwiRmluYWxfZ3JhZGUiLCJJVSIsIlBlcl9jb3JyZWN0IiwiUGVyX2F3YXJlIiwiVGltZV9odyIsIlRpbWVfcHJvbiIsIlRpbWVfTFMiLCJQZXJfY29ycmVjdF9odyIsIlBlcl9jb21wbGV0ZV9MUyIsIkNsdXN0ZXJUb1RocmVlIiwiQ2x1c3RlclRvRm91ciIpCmBgYAoKYGBge3J9CiNHcmFwaCB0aGUgZGlmZmVyZW50IHNvbHV0aW9ucyAtIFRocmVlIENsdXN0ZXJzLgojU2hhcGVzIGluZGljYXRlIExhbmd1YWdlIEJhY2tncm91bmQuIFRvIGNoYW5nZSB3aGljaCB2YXJpYWJsZSBpcyBtYXJrZWQgYnkgc2hhcGUsIGNoYW5nZSB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGUgaW4gInNoYXBlPUxhbmd1YWdlIgpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhUaW1lX2h3LFBlcl9jb3JyZWN0X2h3LCBncm91cCA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSArIGdlb21fcG9pbnQoKGFlcyhzaGFwZT1MYW5ndWFnZSwgY29sb3IgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFRpbWVfaHcsVGltZV9MUywgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkgKyBnZW9tX3BvaW50KChhZXMoc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhQZXJfY29ycmVjdF9odyxGaW5hbF9ncmFkZSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkgKyBnZW9tX3BvaW50KChhZXMoc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhQZXJfY29ycmVjdCxQZXJfYXdhcmUsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpICsgZ2VvbV9wb2ludCgoYWVzKHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSkKZ2dwbG90KENsdXN0ZXJzLCBhZXMoUGVyX2NvbXBsZXRlX0xTLEZpbmFsX2dyYWRlLCBncm91cCA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSArIGdlb21fcG9pbnQoKGFlcyhzaGFwZT1MYW5ndWFnZSwgY29sb3IgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFBlcl9jb21wbGV0ZV9MUyxJVSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkgKyBnZW9tX3BvaW50KChhZXMoc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhUaW1lX0xTLEZpbmFsX2dyYWRlLCBncm91cCA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSArIGdlb21fcG9pbnQoKGFlcyhzaGFwZT1MYW5ndWFnZSwgY29sb3IgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKElVLEZpbmFsX2dyYWRlLCBncm91cCA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSArIGdlb21fcG9pbnQoKGFlcyhzaGFwZT1MYW5ndWFnZSwgY29sb3IgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKElVLFRpbWVfTFMsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpICsgZ2VvbV9wb2ludCgoYWVzKHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9UaHJlZSkpKSkKZ2dwbG90KENsdXN0ZXJzLCBhZXMoSVUsVGltZV9odywgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvVGhyZWUpKSkgKyBnZW9tX3BvaW50KChhZXMoc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb1RocmVlKSkpKQpgYGAKCmBgYHtyfQojR3JhcGggdGhlIGRpZmZlcmVudCBzb2x1dGlvbnMgLSBGb3VyIENsdXN0ZXJzLgojU2hhcGVzIGluZGljYXRlIExhbmd1YWdlIEJhY2tncm91bmQuIFRvIGNoYW5nZSB3aGljaCB2YXJpYWJsZSBpcyBtYXJrZWQgYnkgc2hhcGUsIGNoYW5nZSB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGUgaW4gInNoYXBlPUxhbmd1YWdlCmdncGxvdChDbHVzdGVycywgYWVzKFRpbWVfaHcsUGVyX2NvcnJlY3RfaHcsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkgKyBnZW9tX3BvaW50KChhZXMoc2l6ZT0yLHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9Gb3VyKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhUaW1lX2h3LFRpbWVfTFMsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkgKyBnZW9tX3BvaW50KChhZXMoc2l6ZT0yLHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9Gb3VyKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhQZXJfY29ycmVjdF9odyxGaW5hbF9ncmFkZSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSArIGdlb21fcG9pbnQoKGFlcyhzaXplPTIsc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFBlcl9jb3JyZWN0LFBlcl9hd2FyZSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSArIGdlb21fcG9pbnQoKGFlcyhzaXplPTIsc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFBlcl9jb21wbGV0ZV9MUyxGaW5hbF9ncmFkZSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSArIGdlb21fcG9pbnQoKGFlcyhzaXplPTIsc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFBlcl9jb21wbGV0ZV9MUyxJVSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSArIGdlb21fcG9pbnQoKGFlcyhzaXplPTIsc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKFRpbWVfTFMsRmluYWxfZ3JhZGUsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkgKyBnZW9tX3BvaW50KChhZXMoc2l6ZT0yLHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9Gb3VyKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhJVSxGaW5hbF9ncmFkZSwgZ3JvdXAgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSArIGdlb21fcG9pbnQoKGFlcyhzaXplPTIsc2hhcGU9TGFuZ3VhZ2UsIGNvbG9yID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkpCmdncGxvdChDbHVzdGVycywgYWVzKElVLFRpbWVfTFMsIGdyb3VwID0gZmFjdG9yKENsdXN0ZXJUb0ZvdXIpKSkgKyBnZW9tX3BvaW50KChhZXMoc2l6ZT0yLHNoYXBlPUxhbmd1YWdlLCBjb2xvciA9IGZhY3RvcihDbHVzdGVyVG9Gb3VyKSkpKQpnZ3Bsb3QoQ2x1c3RlcnMsIGFlcyhJVSxUaW1lX2h3LCBncm91cCA9IGZhY3RvcihDbHVzdGVyVG9Gb3VyKSkpICsgZ2VvbV9wb2ludCgoYWVzKHNpemU9MixzaGFwZT1MYW5ndWFnZSwgY29sb3IgPSBmYWN0b3IoQ2x1c3RlclRvRm91cikpKSkKYGBgCgoKCmBgYHtyfQojRGVzY3JpcHRpdmUgc3RhdHMgZm9yIGVhY2ggY2x1c3RlciBpbiB0aGUgNCBjbHVzdGVyIHNvbHV0aW9uClVuc2NhbGVkQ2x1c3RlcnM8LWRhdGEuZnJhbWUoTWFzdGVyRGF0YSwgYXMuZmFjdG9yKHRocmVlY2x1c3RlcmttZWFucyRjbHVzdGVyKSwgYXMuZmFjdG9yKGZvdXJjbHVzdGVya21lYW5zJGNsdXN0ZXIpKQpuYW1lcyhVbnNjYWxlZENsdXN0ZXJzKSA8LSBjKCJJRCIsIlNleCIsIkxhbmd1YWdlIiwiRmluYWxfZ3JhZGUiLCJJVSIsIlBlcl9jb3JyZWN0IiwiUGVyX2F3YXJlIiwiVGltZV9odyIsIlRpbWVfcHJvbiIsIlRpbWVfTFMiLCJQZXJfY29ycmVjdF9odyIsIlBlcl9jb21wbGV0ZV9MUyIsIkNsdXN0ZXJUb1RocmVlIiwiQ2x1c3RlclRvRm91ciIpCiNjcmVhdGluZyBsYW5ndWFnZXMgdmVjdG9yIGFuZCBsYW5ndWFnZSBjb3VudCBkZgpsYW5ncyA8LSBjKCJFbmdsaXNoIiwiU3BhbmlzaCIsIkNyZW9sZSIpCkxhbmdzQ291bnQgPC0gZGF0YS5mcmFtZShjbHVzdGVyMWNvdW50PWludGVnZXIoKSwgY2x1c3RlcjJjb3VudD1pbnRlZ2VyKCksIGNsdXN0ZXIzY291bnQ9aW50ZWdlcigpLCBjbHVzdGVyNGNvdW50PWludGVnZXIoKSwgc3RyaW5nc0FzRmFjdG9ycz1UUlVFKQoKZm9yIChqIGluIGxhbmdzKSB7CiAgICBMYW5nc0NvdW50W2osMV0gPC0gagogICAgZm9yIChpIGluIDE6NCl7CiAgICAgIExhbmdzQ291bnRbaixpXSA8LSBzdW0oVW5zY2FsZWRDbHVzdGVycyRMYW5ndWFnZT09aiAmIFVuc2NhbGVkQ2x1c3RlcnMkQ2x1c3RlclRvRm91cj09aSkKfQp9CmBgYAoKCgo=